package com.app.controller;


import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.app.lzbank.LzBankPayService;
import com.app.lzbank.utils.SerialNoGenUtils;
import com.app.mapper.*;
import com.app.model.PaymentOrder;
import com.app.model.User;
import com.app.service.IFwjzService;
import com.app.service.IPaymentOrderService;
import com.app.service.IZnjLogService;
import com.app.util.PriceUtils;
import com.app.util.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * <p>
 * 订单记录 前端控制器
 * </p>
 *
 * @author yoominic
 * @since 2025-03-18
 */
@Slf4j
@Api(tags = "订单记录")
@RestController
@RequestMapping("/paymentOrder")
public class PaymentOrderController {

    @Value("${wx.pay.mchId}")
    private String mchId;
    @Value("${wx.pay.paymentOrderCallback}")
    private String paymentOrderCallbackUrl;

    @Autowired
    private IPaymentOrderService paymentOrderService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WxPayService wxService;

    @Autowired
    private TenantRelationshipMapper tenantRelationshipMapper;

    @Autowired
    private IFwjzService fwjzService;

    @Autowired
    private FwMapper fwMapper;

    @Autowired
    private IZnjLogService znjLogService;

    @Autowired
    private PropertyFeeLogMapper propertyFeeLogMapper;

    @Autowired
    private LzBankPayService lzBankPayService;

    @ApiOperation(value = "创建订单---拉起微信支付", notes = "创建订单---拉起微信支付")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, paramType = "header"),
            @ApiImplicitParam(name = "paymentOrder", value = "订单信息", required = true, paramType = "body")
    })
    @Transactional
    @PostMapping("/createPaymentOrder")
    public Result createPaymentOrder(HttpServletRequest request,@RequestBody PaymentOrder paymentOrder) {
        //获取请求IP
        String ip = request.getHeader("x-forwarded-for");
        String token = request.getHeader("token");
        String userId = StpUtil.getLoginIdByToken(token).toString();

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",userId);
        User user = userMapper.selectOne(queryWrapper);
        if(user == null){
            return Result.error("用户不存在");
        }

        String orderId = SerialNoGenUtils.genSerialNoByTimestamp();
        paymentOrder.setOrderId(orderId);
        paymentOrder.setUserId(Integer.parseInt(userId));
        paymentOrder.setCreateTime(LocalDateTime.now());
        paymentOrder.setPayStatus(0);
        paymentOrder.setPaymentType(1);

        //计算是否有合并价格
        BigDecimal totalPayableAmount = new BigDecimal(0);
        if(paymentOrder.getPayableDeposit() != null && paymentOrder.getPayableDeposit().compareTo(BigDecimal.ZERO) > 0){//保证金
            totalPayableAmount = totalPayableAmount.add(paymentOrder.getPayableDeposit());
        }
        if (paymentOrder.getPayableRent() != null && paymentOrder.getPayableRent().compareTo(BigDecimal.ZERO) > 0){//房租
            totalPayableAmount = totalPayableAmount.add(paymentOrder.getPayableRent());
        }
        if (paymentOrder.getPayableLateFee() != null && paymentOrder.getPayableLateFee().compareTo(BigDecimal.ZERO) > 0){//滞纳金
            totalPayableAmount = totalPayableAmount.add(paymentOrder.getPayableLateFee());
        }
        if (paymentOrder.getPayablePropertyFee() != null && paymentOrder.getPayablePropertyFee().compareTo(BigDecimal.ZERO) > 0){//物业费
            totalPayableAmount = totalPayableAmount.add(paymentOrder.getPayablePropertyFee());
        }
        //计算是否有合并价格
        BigDecimal totalPayment = new BigDecimal(0);
        if(paymentOrder.getDepositPaid() != null && paymentOrder.getDepositPaid().compareTo(BigDecimal.ZERO) > 0){//保证金
             totalPayment = totalPayment.add(paymentOrder.getDepositPaid());
        }
        if (paymentOrder.getRent() != null && paymentOrder.getRent().compareTo(BigDecimal.ZERO) > 0){//房租
            totalPayment = totalPayment.add(paymentOrder.getRent());
        }
        if (paymentOrder.getLateFee() != null && paymentOrder.getLateFee().compareTo(BigDecimal.ZERO) > 0){//滞纳金
            totalPayment = totalPayment.add(paymentOrder.getLateFee());
        }
        if (paymentOrder.getPropertyFee() != null && paymentOrder.getPropertyFee().compareTo(BigDecimal.ZERO) > 0){//物业费
            totalPayment = totalPayment.add(paymentOrder.getPropertyFee());
        }

        paymentOrder.setType(1);
        paymentOrder.setTotalPaymentAmount(totalPayment);
        paymentOrder.setTotalPayableAmount(totalPayableAmount);
        paymentOrderService.save(paymentOrder);

        return Result.success(lzBankPayService.preOrder2LzBank(orderId, user.getOpenId(), totalPayment, "缴纳房租费", "微信订单详情", "8.8.8.8"));
    }
    @ApiOperation(value = "支付回调", notes = "支付回调")
    @RequestMapping("notify/paymentOrderCallback")
    public void paymentOrderCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.info("【房屋缴费支付支付异步通知】接收到的报文：{}", request.getInputStream());
        String xmlData = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
        log.info("【房屋缴费兰州银行-支付异步通知】接收到的报文：{}", xmlData);
        lzBankPayService.payCallBack2LzBank(request, response);
    }

    @Autowired
    private PaymentOrderMapper paymentOrderMapper;



    @ApiOperation(value = "获取用户缴费记录", notes = "获取用户缴费记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, paramType = "header"),
            @ApiImplicitParam(name = "page", value = "页码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "limit", value = "每页数量", required = true, paramType = "query"),
            @ApiImplicitParam(name = "type", value = "订单类型（1房租缴费、2保证金缴费、3滞纳金缴费、4物业费缴费、5组合缴费）", required = false, paramType = "query")
    })

    @GetMapping("appletGetLoginUserPaymentOrderLog")
    public Result appletGetLoginUserPaymentOrderLog(HttpServletRequest request,Integer page, Integer limit,String type){

        String token = request.getHeader("token");
        if (token == null) {
            return Result.error( "token不存在");
        }
        String userId =  StpUtil.getLoginIdByToken(token).toString();
        if (userId == null) {
            Result result = new Result(401, "登录失效");
            return result;
        }
        User user = userMapper.selectById(userId);
        Page<PaymentOrder> orderPage = new Page<>(page, limit);
        IPage<PaymentOrder> pageList = paymentOrderMapper.appletGetLoginUserPaymentOrderLog(orderPage, user.getId(),type);
        JSONObject result = new JSONObject();
        result.put("total", pageList.getTotal());
        result.put("list", pageList.getRecords());
        return Result.success(result);
    }


    @ApiOperation(value = "管理员获取缴费记录", notes = "管理员获取缴费记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "limit", value = "每页数量", required = true, paramType = "query"),
            @ApiImplicitParam(name = "orderType", value = "订单类型（1房租缴费、2保证金缴费、3滞纳金缴费、4物业费缴费、5组合缴费）", required = false, paramType = "query"),
            @ApiImplicitParam(name = "payStatus", value = "支付状态（0 未支付 1已支付）", required = false, paramType = "query"),
            @ApiImplicitParam(name = "invoiceStatus", value = "发票状态（0 未开票 1已开票）", required = false, paramType = "query"),
            @ApiImplicitParam(name = "receiptStatus", value = "收据状态（0 未生成 1已生成）", required = false, paramType = "query"),
            @ApiImplicitParam(name = "houseType", value = "房屋类型", required = false, paramType = "query"),
            @ApiImplicitParam(name = "fwkeyword", value = "房屋关键字", required = false, paramType = "query"),
            @ApiImplicitParam(name = "yhkeyword", value = "业主关键字", required = false, paramType = "query"),
            @ApiImplicitParam(name = "payTime", value = "缴费时间段开始时间", required = false, paramType = "query"),
            @ApiImplicitParam(name = "untilPayTime", value = "缴费时间段结束时间", required = false, paramType = "query"),
            @ApiImplicitParam(name = "orderPayStartTime", value = "订单支付开始时间", required = false, paramType = "query"),
            @ApiImplicitParam(name = "orderPayEndTime", value = "订单支付结束时间", required = false, paramType = "query")
    })
    @GetMapping("admin/getPaymentOrderLogList")
    public Result adminGetPaymentOrderLogList(Integer page, Integer limit,Integer orderType,Integer payStatus,Integer invoiceStatus,Integer receiptStatus,Integer houseType,
                                              String fwkeyword,String yhkeyword,String payTime,String untilPayTime,String orderPayStartTime,String orderPayEndTime){

        Page<PaymentOrder> orderPage = new Page<>(page, limit);

        IPage<PaymentOrder> pageList = paymentOrderMapper.adminGetPaymentOrderLogList(orderPage, orderType, payStatus, invoiceStatus,receiptStatus, houseType,
                fwkeyword,yhkeyword,payTime,untilPayTime,orderPayStartTime,orderPayEndTime);

        JSONObject result = new JSONObject();
        result.put("total", pageList.getTotal());
        result.put("list", pageList.getRecords());
        return Result.success(result);
    }



    @ApiOperation(value = "获取缴费记录统计", notes = "获取缴费记录统计")
    @GetMapping("admin/getPaymentOrderTopStatistics")
    public Result getPaymentOrderTopStatistics(){

        JSONObject result = new JSONObject();
        Map<String, Object> map = paymentOrderMapper.getPaymentOrderTopStatistics();
        //应缴总金额
        result.put("totalPayableAmount", map.get("total_payable_amount"));
        //实付总金额
        result.put("totalPaymentAmount", map.get("total_payment_amount"));
        //线上
        result.put("onlinePayableAmount", map.get("total_payment_amount_type_1"));
        //线下
        result.put("offlinePayableAmount", map.get("total_payment_amount_type_2"));
        return Result.success(result);
    }


    @PostMapping("admin/savaPaymentOrderLog")
    public Result savaPaymentOrderLog(HttpServletRequest request,@RequestBody PaymentOrder paymentOrder){


        return Result.success(paymentOrder);
    }

}

